import redis
import jwt
from django.core.exceptions import ObjectDoesNotExist
from django.shortcuts import get_object_or_404
import json, random, string
from django.views import View
from hashlib import sha256
from patient.models import Patient, Doctor, Hospital, User, HospitalEscort, EscortServiceItem, Department, Orders
from patient.smscode import Msg_Verification_Code
from .qiniu import qiuniuImg, QiniuManage
from django.http.response import HttpResponse, JsonResponse


class RegsterloginView(View):
    """用户信息的注册登录（手机号、密码）"""

    def post(self, request):
        data = json.loads(request.body)
        print("<<<<", data)
        name = data['phone']
        pwd = data['common_pwd']
        hash_pwd = sha256(pwd.encode('utf-8')).hexdigest()
        if not all([name, pwd]):
            return JsonResponse({'code': 400, 'msg': '字段不能为空'})
        user = User.objects.filter(phone=name).first()
        print("user<<<", user)
        if user:
            if user.common_pwd == hash_pwd:
                return JsonResponse({'code': 200, 'msg': '登录成功'})
            else:
                return JsonResponse({'code': 400, 'msg': '密码错误'})
        else:
            User.objects.create(phone=name, common_pwd=hash_pwd)
            encoded_jwt = jwt.encode(
                {'username': name, 'site': 'https://www.baidu.com'},
                'secret_key',
                algorithm='HS256')
            print('<<<<<<token', encoded_jwt)
            return JsonResponse({'code': 200, 'msg': '注册登录成功', 'token': encoded_jwt})

    def get(self, request):
        """通过手机号查询用户信息"""
        phone = request.GET.get('phone')
        print("/////", phone)
        try:
            user = User.objects.get(phone=phone)
            print('<<<<<<', user)
            return JsonResponse({
                'phone': user.phone or None,
                'address': user.address_message or None,
                'nickname': user.nickname or None,
                'avatar': user.p_profile_picture or None,
                'password': user.common_pwd or None,
            })
        except User.DoesNotExist:
            return JsonResponse({'error': '用户不存在'}, status=404)
        except Exception as e:
            return JsonResponse({'error': f'查询用户信息出错: {str(e)}'}, status=500)

    def put(self, request, phone):
        """通过用户手机号更新用户信息"""
        try:
            data = json.loads(request.body)
            new_avatar = data.get('avatar')
            new_address = data.get('address')
            new_nickname = data.get('nickname')
            if new_avatar:
                User.objects.filter(phone=phone).update(p_profile_picture=new_avatar)
                return JsonResponse({'message': '修改头像成功'}, status=200)
            if new_address:
                User.objects.filter(phone=phone).update(address_message=new_address)
                return JsonResponse({'message': '修改地址成功'}, status=200)
            if new_nickname:
                User.objects.filter(phone=phone).update(nickname=new_nickname)
                return JsonResponse({'message': '修改昵称成功'}, status=200)
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)


class PatientLoginView(View):
    """陪诊师登录"""

    def post(self, request):
        try:
            data = json.loads(request.body)
            phone = data['phone']
            pwd = data['common_pwd']
            if not phone:
                return JsonResponse({'code': 400, 'msg': '手机号不能为空'})
        except Exception as e:
            return JsonResponse(str(e), status=400, safe=False)

        try:
            user_phone = HospitalEscort.objects.filter(e_phone=phone).first()
            hash_pwd = sha256(pwd.encode('utf-8')).hexdigest()
            if user_phone:
                if user_phone.e_password == hash_pwd:
                    encoded_jwt = jwt.encode(
                        {'username': phone, 'site': 'https://www.baidu.com'},
                        'secret_key',
                        algorithm='HS256')
                    return JsonResponse({'code': 200, 'msg': '登录成功', 'token': encoded_jwt}, status=200)
                return JsonResponse({'code': 400, 'msg': '密码错误'}, status=400)
            else:
                HospitalEscort.objects.create(e_phone=phone, e_password=hash_pwd, e_name='默认用户', favorable_rate=0,
                                              order_count=0,
                                              img='https://pic4.zhimg.com/v2-89645d664e2b048afd8060c7ed8cc5e3_r.jpg')
                encoded_jwt = jwt.encode(
                    {'username': phone, 'site': 'https://www.baidu.com'},
                    'secret_key',
                    algorithm='HS256')

                return JsonResponse({'code': 200, 'msg': '注册成功, 自动登录', 'token': encoded_jwt})
        except Exception as e:
            return JsonResponse(str(e), status=400, safe=False)


class EscortCertification(View):
    """陪诊师认证"""

    def post(self, request):
        data = json.loads(request.body)
        phone = data['e_phone']
        escort_info = HospitalEscort.objects.filter(e_phone=phone)
        if escort_info:
            checked = data.get('groupChecked', [])
            print(checked)
            del data['groupChecked']
            if data['address'] == '':
                del data['address']
            if data['e_age'] == '':
                del data['e_age']
            update_info = HospitalEscort.objects.filter(e_phone=phone).update(**data)
            print(update_info)
            # HospitalEscort.objects.create(e_sex=sex, address=address, e_card=card)
            if update_info == 0:
                return JsonResponse({'error': '信息没有更新，可能是数据有误'}, status=501)
            services = [EscortServiceItem.objects.get(id=i) for i in checked]
            escort = HospitalEscort.objects.filter(e_phone=phone).first()
            escort.service_items.add(*services)
            escort.occupancy = '已入驻'
            escort.save()
            return JsonResponse('提交陪诊师实名认证成功', status=200, safe=False)
        else:
            return JsonResponse({'error': '未找到对应手机号的陪诊师记录'}, status=404, safe=False)


class UserUpdateView(View):
    """通过手机号更新用户密码"""

    def post(self, request):
        try:
            data = json.loads(request.body)
            original_phone = data.get('original_phone')
            new_pwd = data.get('new_pwd')
            if not original_phone or not new_pwd:
                return JsonResponse({'code': 400, 'message': '手机号和新密码不能为空'}, status=400)
            new_hashed_pwd = sha256(new_pwd.encode('utf-8')).hexdigest()
            try:
                user = User.objects.filter(phone=original_phone)
                if user:
                    user.update(common_pwd=new_hashed_pwd)
                    return JsonResponse({'code': 200, 'message': '密码更改成功'})
            except ObjectDoesNotExist:
                return JsonResponse({'code': 404, 'message': '用户不存在'}, status=404)
        except json.JSONDecodeError:
            return JsonResponse({'code': 400, 'message': '请求数据格式错误'}, status=400)
        except Exception as e:
            return JsonResponse({'code': 500, 'error': str(e)}, status=500)


class GesturePwdView(View):
    """手势密码"""

    def post(self, request):
        data = json.loads(request.body)
        name = data['phone']
        gesture_pwd = data['password']
        hash_pwd = sha256(gesture_pwd.encode('utf-8')).hexdigest()
        print("<<<<<<gesture_pwd", gesture_pwd)
        user = User.objects.filter(phone=name).first()
        print("user<<<", user)
        if user:
            User.objects.filter(phone=name).update(gesture_pwd=hash_pwd)
            return JsonResponse({'code': 200, 'msg': '手势密码注册成功'})
        else:
            return JsonResponse({'code': 400, 'msg': '没有此用户'})


def redis_save():
    try:
        r = redis.Redis(host='127.0.0.1', port=6379, db=1, decode_responses=True)
        print("<<<<<", r)
        return r
    except Exception as e:
        print("Redis连接失败", e)


class MsgVerificationCodeView(View):
    """验证码发送"""

    def post(self, request):
        data = json.loads(request.body)
        phone = data['phone']
        is_code = Msg_Verification_Code(phone)
        print("code", is_code)
        r = redis_save()
        r.setex(phone, 120, is_code)
        if is_code:
            return JsonResponse({'code': 200, 'msg': '验证码发送成功'})
        else:
            return JsonResponse({'code': 500, 'msg': '验证码发送失败'})


class SmsGetCodeView(View):
    """短信验证码验证"""

    def post(self, request):
        data = json.loads(request.body)
        phone = data['phone']
        sms = data.get('captcha')
        r = redis_save()
        r_sms = r.get(phone)
        # print(r_sms)
        if not phone or not sms:
            return JsonResponse('手机号或验证码不能为空', status=400)
        users = User.objects.filter(phone=phone).first()
        if users:
            if r_sms == sms:
                return JsonResponse({'code': 200, 'msg': '验证码正确'})
            else:
                return JsonResponse('验证码错误', status=400)
        else:
            return JsonResponse('手机号不存在', status=400)


class ResetPwdView(View):
    """重置密码"""

    def post(self, request, phone):
        data = json.loads(request.body)
        new_pwd = data['new_pwd']
        hash_pwd = sha256(new_pwd.encode('utf-8')).hexdigest()
        user = User.objects.filter(phone=phone).first()
        print("user<<<", user)
        if user:
            User.objects.filter(phone=phone).update(common_pwd=hash_pwd)
            return JsonResponse({'code': 200, 'msg': '新密码重置成功'})
        else:
            return JsonResponse({'code': 400, 'msg': '没有此用户'})


class HospitalView(View):
    """医院信息"""

    def post(self, request):
        try:
            data = json.loads(request.body)
            city = data.get('city_name')
            print(('>>>>', city))
            if city:
                hospitals = Hospital.objects.filter(address__contains=city)
                if hospitals:
                    hospital_list = [i.tojson() for i in hospitals]
                    return JsonResponse({'hospital_list': hospital_list}, status=200)
        except Exception as e:
            return JsonResponse({'message': '请求失败', 'error': str(e)}, status=500)

    def get(self, request):
        try:
            hospitals = Hospital.objects.all()
            print("@@@", hospitals)
            hospital_list = [i.tojson() for i in hospitals]
            return JsonResponse({'hospital_list': hospital_list}, status=200)
        except Exception as e:
            return JsonResponse({'message': '请求失败', 'error': str(e)}, status=500)


class InhospitalServiceView(View):
    """院内陪护"""

    def get(self, request):
        services = EscortServiceItem.objects.filter(escort_type='院内陪护').all()
        print("院内陪护", services)
        service_lst = [i.tojson() for i in services]
        return JsonResponse({'service': service_lst}, status=200)


class CompanyServiceView(View):
    """就医陪诊"""

    def get(self, request):
        services = EscortServiceItem.objects.filter(escort_type='就医陪诊').all()
        print("就医陪诊", services)
        service_lst = [i.tojson() for i in services]
        return JsonResponse({'service': service_lst}, status=200)


class PatientView(View):
    """就诊人信息"""

    def get(self, request):
        """查询就诊人"""
        patients = Patient.objects.all()
        patients_lst = []
        for patient in patients:
            patient_info = {
                "id": patient.id,
                'name': patient.name,
                'age': patient.age,
                'sex': patient.sex,
                'phone': patient.phone,
            }
            patients_lst.append(patient_info)
        print("就诊人信息", patients_lst)
        return JsonResponse({'patients': patients_lst})

    def post(self, request):
        """添加就诊人"""
        data = json.loads(request.body)
        name = data['name']
        age = data['age']
        phone = data['phone']
        sex = data['sex']
        if not all([name, age, phone]):
            return JsonResponse({'message': '就诊人信息不能为空'}, status=400)
        try:
            patient = Patient(name=name, age=age, phone=phone, sex=sex)
            patient.save()
            return JsonResponse({'message': '就诊人信息添加成功'}, status=200)
        except Exception as e:
            return JsonResponse({'message': '添加就诊人失败', 'error': str(e)}, status=500)

    def delete(self, request, patient_id):
        """删除就诊人"""
        try:
            patient = Patient.objects.get(id=patient_id)
            patient.delete()
            return JsonResponse({'message': '就诊人删除成功'}, status=200)
        except Patient.DoesNotExist:
            return JsonResponse({'message': '要删除的就诊人不存在'}, status=404)
        except Exception as e:
            return JsonResponse({'message': '删除就诊人失败', 'error': str(e)}, status=500)

    def put(self, request, patient_id):
        """修改就诊人"""
        try:
            patient = Patient.objects.get(id=patient_id)
            data = json.loads(request.body)
            patient.id = data['id']
            patient.name = data['name']
            patient.age = data['age']
            patient.phone = data['phone']
            patient.sex = data['sex']
            patient.save()
            return JsonResponse({'message': '就诊人更新成功'}, status=200)
        except Patient.DoesNotExist:
            return JsonResponse({'message': '要更新的就诊人不存在'}, status=404)
        except Exception as e:
            return JsonResponse({'message': '更新就诊人失败', 'error': str(e)}, status=500)


class EscortInfoView(View):
    """陪诊师信息"""

    def get(self, request):
        sex = request.GET.get('sex', '')
        age = request.GET.get('age', '')
        order = request.GET.get('order', '')
        score = request.GET.get('score', '')
        escorts = HospitalEscort.objects.all()
        if sex:
            escorts = escorts.filter(e_sex=sex)
        if age:
            if age == '<30':
                escorts = escorts.filter(e_age__lt=30)
            elif age == '31~40':
                escorts = escorts.filter(e_age__gte=31, e_age__lte=40)
            elif age == '41~50':
                escorts = escorts.filter(e_age__gte=41, e_age__lte=50)
        if order:
            if order == '0~100':
                escorts = escorts.filter(order_count__gte=0, order_count__lte=100)
            elif order == '101~200':
                escorts = escorts.filter(order_count__gte=101, order_count__lte=200)
            elif order == '201~300':
                escorts = escorts.filter(order_count__gte=201, order_count__lte=300)
            elif order == '301~400':
                escorts = escorts.filter(order_count__gte=301, order_count__lte=400)
        if score:
            if score == '<3.0':
                escorts = escorts.filter(favorable_rate__lt=3.0)
            elif score == '3.0~4.0':
                escorts = escorts.filter(favorable_rate__gte=3.0, favorable_rate__lte=4.0)
            elif score == '4.0~5.0':
                escorts = escorts.filter(favorable_rate__gte=4.0, favorable_rate__lte=5.0)
        escorts_lst = []
        for escort in escorts:
            escort_info = {
                'e_name': escort.e_name,
                'e_phone': escort.e_phone,
                'e_age': escort.e_age,
                'e_sex': escort.e_sex,
                'address': escort.address,
                'favorable_rate': escort.favorable_rate,
                'order_count': escort.order_count,
                'service_items': escort.service_items,
                'status': escort.status,
                'img': escort.img,
            }
            escorts_lst.append(escort_info)
        print("陪诊师信息", escorts_lst)
        return JsonResponse({'escorts': escorts_lst})


class SearchEscortView(View):
    """查询陪诊师"""

    def get(self, request, name):
        try:
            escorts = HospitalEscort.objects.filter(e_name=name).values()
            if not escorts:
                return JsonResponse({'msg': '没有该陪诊师'})
            escorts_lst = []
            for escort in escorts:
                escort_info = {
                    'e_name': escort['e_name'],
                    'e_phone': escort['e_phone'],
                    'e_age': escort['e_age'],
                    'e_sex': escort['e_sex'],
                    'address': escort['address'],
                    'favorable_rate': escort['favorable_rate'],
                    'order_count': escort['order_count'],
                    'service_items': escort['service_items'],
                    'status': escort['status'],
                    'img': escort['img']

                }
                escorts_lst.append(escort_info)
            print("陪诊师信息", escorts_lst)
            return JsonResponse({'escorts': escorts_lst})
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)


class DepartmentView(View):
    """通过医院名查询所有科室信息"""

    def get(self, request):
        hospital_name = request.GET.get('hospital_name')
        if hospital_name:
            try:
                hospital = Hospital.objects.filter(h_name=hospital_name).first()
                if hospital:
                    h_id = hospital.id
                    department = Department.objects.filter(hospital_id=h_id)
                    departments_lst = []
                    for i in department:
                        department_info = {
                            'id': i.id,
                            'professional_department': i.professional_department,
                            'hospital_id': i.hospital.id,
                        }
                        departments_lst.append(department_info)
                        print("科室信息", departments_lst)
                    return JsonResponse({'departments': departments_lst})
                else:
                    return JsonResponse({'message': '没有找到此医院'}, status=404)
            except Exception as e:
                return JsonResponse({'error': str(e)}, status=500)
        return JsonResponse({'message': '没有提供医院名'}, status=400)


class QiniuTokenView(View):
    def get(self, request):
        Qiniu = qiuniuImg()
        token = Qiniu.get_token()
        if token is None:
            return JsonResponse({'error': '获取token失败，token为None'}, status=400)
        return JsonResponse({'token': token}, status=200)


class QiniuDownloadView(View):
    def post(self, request):
        data = json.loads(request.body)
        key = data['key']
        Qiniu = qiuniuImg()
        download_url = Qiniu.download_file(key=key)
        print("//////", download_url)
        if download_url is None:
            return JsonResponse({'error': '获取下载网址失败'}, status=400)
        return JsonResponse({'download_url': download_url}, status=200)


class SubmitFormDataView(View):
    def post(self, request):
        try:
            data = json.loads(request.body)
            user = data['user']
            service_item = data.get('service_item', '')
            hospital = data.get('hospital', '')
            escort = data.get('escort', '')
            patient = data.get('patient', '')
            department = data.get('department', '')
            expect_time = data.get('expect_time', '')
            address = data.get('address', '')
            coupon = data.get('coupon', 0)
            price = data.get('price', 0)
            medicine_name = data.get('medicine_name', '')
            medicine_type = data.get('medicine_type', '')
            receive_info = data.get('receive_info', '')
            doctor = data.get('doctor', '')
            report_info = data.get('report_info', '')
            data_upload = data.get('data_upload', '')
            try:
                user_obj = User.objects.filter(phone=user).first()
            except User.DoesNotExist:
                user_obj = User.objects.create(phone=user)
                print("//////", user_obj)
            Orders.objects.create(
                user=user_obj,
                service_item=service_item,
                hospital=hospital,
                escort=escort,
                patient=patient,
                department=department,
                expect_time=expect_time,
                delivery_address=address,
                coupon=coupon,
                price=price,
                medicine_name=medicine_name,
                medicine_type=medicine_type,
                receive_info=receive_info,
                doctor=doctor,
                report_info=report_info,
                data_upload=data_upload,
            )
            return JsonResponse({"message": "订单存入成功"}, status=200)
        except Exception as e:
            return JsonResponse({"error": str(e)}, status=500)


class UnpaidOrdersView(View):
    """各种订单状态展示"""

    def post(self, request):
        try:
            data = json.loads(request.body)
            status = data.get('status')
            get_all = data.get('get_all')
            if get_all:
                all_orders = Orders.objects.all()
            else:
                all_orders = Orders.objects.filter(status=status)
            order_info = [i.tojson() for i in all_orders]
            return JsonResponse({'order_info': order_info}, status=200)
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)
